package com.wyzz.hr.util.output;

import java.util.*;

import com.wyzz.hr.util.comparator.ListComparator;
import com.wyzz.hr.util.reflect.ObjectProperty;

public class ObjectListToListList {

	public ObjectListToListList() {
	}

	public ObjectListToListList(List inputList, List fieldList) {
		setInputList(inputList);
		setFieldList(fieldList);
	}

	public void transferGroupOrderStatistic() throws Exception {
		transferGroupOrder();
		statistic();
	}

	public List transferGroupOrder() throws Exception {
		groupPlaceList = null;
		listList = null;
		statisticList = null;
		int inputNum = inputList.size();
		int fieldNum = fieldList.size();
		List interList = new ArrayList();
		for (int i = 0; i < inputList.size(); i++)
			interList.add(new ArrayList());

		ObjectProperty objectProperty = new ObjectProperty();
		Class objClass = inputList.get(0).getClass();
		List groupField = new ArrayList();
		List orderField = new ArrayList();
		FormatToString format = new FormatToString();
		for (int i = 0; i < fieldNum; i++) {
			objectProperty.initial(objClass, ((FieldOperate) fieldList.get(i))
					.getFieldName());
			format.setFormat(((FieldOperate) fieldList.get(i)).getDataType(),
					((FieldOperate) fieldList.get(i)).getFormat());
			for (int j = 0; j < inputList.size(); j++)
				((List) interList.get(j)).add(format.format(objectProperty
						.getProperty(inputList.get(j))));

			if (Math.abs(((FieldOperate) fieldList.get(i)).getGroupOrder()) == 1) {
				orderField.add(Integer.valueOf(i));
				continue;
			}
			if (Math.abs(((FieldOperate) fieldList.get(i)).getGroupOrder()) == 2)
				groupField.add(Integer.valueOf(i));
		}

		int groupFieldNum = groupField.size();
		int orderFieldNum = orderField.size();
		List resultList = null;
		ListComparator listComparator = new ListComparator();
		int groupArr[][] = (int[][]) null;
		if (groupFieldNum == 0) {
			resultList = new ArrayList();
			resultList.add(interList);
		} else {
			groupArr = new int[groupFieldNum][2];
			for (int i = 0; i < groupFieldNum; i++) {
				groupArr[i][0] = ((Integer) groupField.get(i)).intValue();
				groupArr[i][1] = ((FieldOperate) fieldList.get(groupArr[i][0]))
						.getGroupOrder();
			}

			listComparator.setOrderArr(groupArr);
			resultList = new ArrayList();
			List signList = new ArrayList();
			signList.add(interList.get(0));
			List tmpList = new ArrayList();
			tmpList.add(interList.get(0));
			resultList.add(tmpList);
			for (int i = 1; i < inputNum; i++) {
				List list1 = (List) interList.get(i);
				int groupNum = signList.size();
				int j = 0;
				do {
					if (j >= groupNum)
						break;
					int compareResult = listComparator.compare(list1,
							(List) signList.get(j));
					if (compareResult == 0) {
						((List) resultList.get(j)).add(list1);
						break;
					}
					if (compareResult < 0) {
						signList.add(j, list1);
						List tmpList1 = new ArrayList();
						tmpList1.add(list1);
						resultList.add(j, tmpList1);
						break;
					}
					j++;
				} while (true);
				if (j == groupNum) {
					signList.add(list1);
					List tmpList1 = new ArrayList();
					tmpList1.add(list1);
					resultList.add(tmpList1);
				}
			}

		}
		int groupNum = resultList.size();
		if (orderFieldNum > 0) {
			int orderArr[][] = new int[orderFieldNum][2];
			for (int i = 0; i < orderFieldNum; i++) {
				orderArr[i][0] = ((Integer) orderField.get(i)).intValue();
				orderArr[i][1] = ((FieldOperate) fieldList.get(orderArr[i][0]))
						.getGroupOrder();
			}

			listComparator.setOrderArr(orderArr);
			for (int i = 0; i < groupNum; i++) {
				List allListTmp = (List) resultList.get(i);
				Collections.sort((List) resultList.get(i), listComparator);
			}

		}
		listList = new ArrayList();
		groupPlaceList = new ArrayList();
		groupPlaceList.add(new ArrayList());
		for (int i = 0; i < groupNum; i++) {
			((List) groupPlaceList.get(0))
					.add(Integer.valueOf(listList.size()));
			listList.addAll((Collection) resultList.get(i));
		}

		if (groupFieldNum > 0) {
			for (int i = 1; i < groupFieldNum; i++) {
				groupPlaceList.add(new ArrayList());
				int groupArrNew[][] = new int[groupFieldNum - i][2];
				for (int j = 0; j < groupArrNew.length; j++) {
					groupArrNew[j][0] = groupArr[j][0];
					groupArrNew[j][1] = groupArr[j][1];
				}

				listComparator.setOrderArr(groupArrNew);
				int sizeI = ((List) groupPlaceList.get(i - 1)).size();
				((List) groupPlaceList.get(i)).add(Integer.valueOf(0));
				for (int j = 1; j < sizeI; j++) {
					int indexBgn = ((Integer) ((List) groupPlaceList.get(i - 1))
							.get(j - 1)).intValue();
					int indexEnd = ((Integer) ((List) groupPlaceList.get(i - 1))
							.get(j)).intValue();
					if (listComparator.compare((List) listList.get(indexBgn),
							(List) listList.get(indexEnd)) != 0)
						((List) groupPlaceList.get(i)).add(Integer
								.valueOf(indexEnd));
				}

			}

			groupPlaceList.add(new ArrayList());
			((List) groupPlaceList.get(groupFieldNum)).add(Integer.valueOf(0));
		}
		for (int i = 0; i < groupFieldNum + 1; i++)
			((List) groupPlaceList.get(i)).add(Integer.valueOf(inputNum));

		return listList;
	}

	public List statistic() throws Exception {
		statisticList = new ArrayList();
		Statistic statistic = new Statistic(listList, groupPlaceList);
		for (int i = 0; i < fieldList.size(); i++) {
			FieldOperate tmpField = (FieldOperate) fieldList.get(i);
			List resultTmp = statistic.statistic(tmpField.getStatisticMethod(),
					i);
			statisticList.add(resultTmp);
		}
		return statisticList;
	}

	public String[][] getListListToString() throws Exception {
		int fieldNum = fieldList.size();
		int listNum = listList.size();
		String result[][] = new String[listNum][fieldNum];
		FormatToString format = new FormatToString();
		for (int i = 0; i < fieldNum; i++) {
			format.setFormat(((FieldOperate) fieldList.get(i)).getDataType(),
					((FieldOperate) fieldList.get(i)).getFormat());
			for (int j = 0; j < listNum; j++)
				result[j][i] = format.toStringAfterFormat(((List) listList
						.get(j)).get(i));

		}

		return result;
	}

	public List getStatisticListToString() throws Exception {
		int fieldNum = fieldList.size();
		List result = new ArrayList();
		FormatToString format = new FormatToString();
		List nullStr = new ArrayList();
		for (int i = 0; i < groupPlaceList.size(); i++) {
			nullStr.add(new ArrayList());
			for (int j = 1; j < ((List) groupPlaceList.get(i)).size(); j++)
				((List) nullStr.get(i)).add("");

		}

		for (int i = 0; i < fieldNum; i++) {
			List fieldListTmp = (List) statisticList.get(i);
			if (fieldListTmp == null) {
				result.add(nullStr);
				continue;
			}
			List resultField = new ArrayList();
			format.setFormat(((FieldOperate) fieldList.get(i))
					.getStatisticDataType(), ((FieldOperate) fieldList.get(i))
					.getStatisticFormat());
			for (int j = 0; j < fieldListTmp.size(); j++) {
				List resultElement = new ArrayList();
				for (int k = 0; k < ((List) fieldListTmp.get(j)).size(); k++)
					resultElement.add(format
							.toStringAfterFormat(((List) fieldListTmp.get(j))
									.get(k)));

				resultField.add(resultElement);
			}

			result.add(resultField);
		}

		return result;
	}

	public void setFieldList(List fieldList) {
		this.fieldList = fieldList;
	}

	public void setInputList(List inputList) {
		this.inputList = inputList;
	}

	public List getInputList() {
		return inputList;
	}

	public List getFieldList() {
		return fieldList;
	}

	public List getStatisticResult() {
		return statisticResult;
	}

	public List getListList() {
		return listList;
	}

	public List getStatisticList() {
		return statisticList;
	}

	public List getGroupPlaceList() {
		return groupPlaceList;
	}

	private List inputList;
	private List fieldList;
	private List statisticResult;
	private List listList;
	private List statisticList;
	private List groupPlaceList;
}
